package com.rdxer.api;

import com.rdxer.dataview.UploadUrlDV;
import com.rdxer.model.Attachment;
import com.rdxer.core.security.AppUserDetails;
import com.rdxer.service.AttachmentService;
import com.rdxer.core.entity.Result;
import com.rdxer.core.entity.StatusCode;
import com.rdxer.core.ex.ObjectEx;
import io.minio.MinioClient;
import io.minio.errors.*;
import lombok.Getter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.xmlpull.v1.XmlPullParserException;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.UUID;

@CrossOrigin
@RestController
public class FileController {
    @Value("${minio.endpoint}")
    private String endpoint;
    @Value("${minio.accessKey}")
    private String accessKey;
    @Value("${minio.secretKey}")
    private String secretKey;
    @Getter
    @Value("${minio.bucketName}")
    private String bucketName;

    @Getter
    MinioClient minioClient;
    @Autowired
    AttachmentService attachmentService;

    @PostConstruct
    void init() {
        try {
            minioClient = new MinioClient(endpoint, accessKey, secretKey);
        } catch (InvalidEndpointException | InvalidPortException e) {
            e.printStackTrace();
        }
    }

    @GetMapping("/uploadUrl")
    public Result<UploadUrlDV> uploadUrl(String fileName) {

        // 使用MinIO服务的URL，端口，Access key和Secret key创建一个MinioClient对象
        // asdasdasdasdas-bg.png
        // 文件的 md5
        // UUID
        // 时间戳 - 有可能会重复
        try {

//            boolean isExist = minioClient.bucketExists(bucketName);
//            if (!isExist) {
//                // 创建一存储桶
//                minioClient.makeBucket(bucketName);
//            }

            String objName = UUID.randomUUID().toString() + "--" + fileName;

            String putURL = minioClient.presignedPutObject(bucketName, objName);

            String url = String.format("%s/%s/%s", endpoint, bucketName, objName);
            Attachment attachment = new Attachment();
            attachment.setFilename(fileName);
            String[] split = fileName.trim().split("\\.");
            attachment.setType(split[split.length - 1]);

            ObjectEx.getByReturn(() -> AppUserDetails.getCurrent().account.getId(), r -> {
                attachment.setUid(r);
            });

            attachment.setUrl(url);
            attachment.setPutUrl(putURL);
            attachment.setHost(endpoint);
            attachment.setPath(url.replace(endpoint, ""));

            attachmentService.add(attachment);

            return new Result<UploadUrlDV>() {{
                setData(UploadUrlDV.builder()
                        .getURL(url)
                        .putURL(putURL)
                        .attachment(attachment)
                        .build());
            }};
        } catch (InvalidKeyException | NoSuchAlgorithmException | NoResponseException | XmlPullParserException | InvalidBucketNameException | InsufficientDataException | ErrorResponseException | InternalException | IOException e) {
            e.printStackTrace();
            return new Result() {{
                setCode(StatusCode.ERROR);
                setMessage("文件桶不存在，保存失败.");
            }};
        } catch (InvalidExpiresRangeException e) {
            e.printStackTrace();
            return new Result() {{
                setCode(StatusCode.ERROR);
                setMessage("生成URL失败.");
            }};
        }
    }

    // 暂时不用
    @PostMapping("/upload")
    Result upload(@RequestParam("file") MultipartFile file) {

        // 使用MinIO服务的URL，端口，Access key和Secret key创建一个MinioClient对象
        // asdasdasdasdas-bg.png
        // 文件的 md5
        // UUID
        // 时间戳 - 有可能会重复
        try {

            boolean isExist = minioClient.bucketExists(bucketName);
            if (!isExist) {
                // 创建一个名为asiatrip的存储桶，用于存储照片的zip文件。
                minioClient.makeBucket(bucketName);
            }

            String objName = UUID.randomUUID().toString() + "--" + file.getOriginalFilename();
            minioClient.putObject(bucketName, objName, file.getInputStream(), file.getContentType());
            return new Result() {{
                setData(objName);
            }};
        } catch (InvalidKeyException | NoSuchAlgorithmException | NoResponseException | XmlPullParserException | InvalidBucketNameException | InsufficientDataException | ErrorResponseException | InternalException | IOException e) {
            e.printStackTrace();
            return new Result() {{
                setCode(StatusCode.ERROR);
                setMessage("文件桶不存在，保存失败.");
            }};
        } catch (RegionConflictException e) {
            e.printStackTrace();
            return new Result() {{
                setCode(StatusCode.ERROR);
                setMessage("创建文件桶失败，保存失败.");
            }};
        } catch (InvalidArgumentException e) {
            e.printStackTrace();
            return new Result() {{
                setCode(StatusCode.ERROR);
                setMessage("转存失败，保存失败.");
            }};
        }
    }

    // 暂时不用
    @GetMapping("/download/{objName}")
    void download(@PathVariable String objName, HttpServletResponse response) {
        try {
            String url = minioClient.presignedGetObject(bucketName, objName);
            response.sendRedirect(url);
        } catch (InvalidBucketNameException | NoSuchAlgorithmException | InsufficientDataException | IOException | InvalidKeyException | NoResponseException | XmlPullParserException | ErrorResponseException | InternalException | InvalidExpiresRangeException e) {
            e.printStackTrace();

        }
    }
}
